#ifndef QXGAME_GAMEVECTOR_H
#define QXGAME_GAMEVECTOR_H

#include <cmath>

class GameVector {
public:
    GameVector() = default;
    ~GameVector() = default;

    GameVector(double x, double y)
            : x(x), y(y)
    {}

    GameVector operator+(const GameVector &vec) const
    {
        return {x + vec.x, y + vec.y};
    }

    void operator+=(const GameVector &vec)
    {
        x += vec.x, y += vec.y;
    }

    GameVector operator-(const GameVector &vec) const
    {
        return {x - vec.x, y - vec.y};
    }

    void operator-=(const GameVector &vec)
    {
        x -= vec.x, y -= vec.y;
    }

    double operator*(const GameVector &vec) const
    {
        return x * vec.x + y * vec.y;
    }

    double operator^(const GameVector &vec) const
    {
        return x * vec.y - y * vec.x;
    }

    GameVector operator*(double val) const
    {
        return {x * val, y * val};
    }

    GameVector operator/(double val) const
    {
        return {x / val, y / val};
    }

    void operator*=(double val)
    {
        x *= val, y *= val;
    }

    void operator/=(double val)
    {
        x /= val, y /= val;
    }

    bool operator==(const GameVector &vec) const
    {
        return x == vec.x && y == vec.y;
    }

    bool operator>(const GameVector &vec) const
    {
        return Length() > vec.Length();
    }

    bool operator<(const GameVector &vec) const
    {
        return Length() < vec.Length();
    }

    GameVector Vertical() const
    {
        return {-y, x};
    }

    double Length() const
    {
        return std::sqrt(x * x + y * y);
    }

    GameVector Normalize() const
    {
        double len = Length();
        if (len == 0) {
            return {0, 0};
        }
        return {x / len, y / len};
    }

    bool ApproxZero() const
    {
        return Length() < 1e-6;
    }

public:
    double x = 0;
    double y = 0;
};

#endif //QXGAME_GAMEVECTOR_H
